package epoch.game.core.net;

import java.util.HashMap;
import java.util.Map;

import org.apache.logging.log4j.Logger;

import epoch.game.core.common.Loggers;
import epoch.game.core.handler.IMessageHandler;

/**
 * 消息注册服务
 * 
 * @author will
 *
 */
public class MessageRouter<T> {

	private static Logger logger = Loggers.MSG_LOGGER;
	private Map<Integer, Class<? extends T>> msgClasses = new HashMap<Integer, Class<? extends T>>();
	private Map<Class<? extends T>, Integer> classeMsgs = new HashMap<Class<? extends T>, Integer>();
	private Map<Class<? extends T>, Class<? extends IMessageHandler<? extends T>>> msgAndHandlerClasses = new HashMap<Class<? extends T>, Class<? extends IMessageHandler<? extends T>>>();
	private Map<Class<? extends T>, IMessageHandler<? extends T>> handlers = new HashMap<Class<? extends T>, IMessageHandler<? extends T>>();

	/**
	 * 注册消息处理器
	 *
	 * @param msg
	 * @param handlerClass
	 * @param <M>
	 * @param <H>
	 */
	public <M extends T, H extends IMessageHandler<? extends T>> void register(int msgId, Class<M> msgClass, Class<H> handlerClass) {
		if (msgClasses.containsKey(msgId)) {
			if (msgClass != msgClasses.get(msgId)) {
				throw new IllegalArgumentException("消息id重复：" + msgClass.getSimpleName() + "," + msgClasses.get(msgId).getSimpleName());
			}
		}
		msgAndHandlerClasses.put(msgClass, handlerClass);
		msgClasses.put(msgId, msgClass);
		classeMsgs.put(msgClass, msgId);
		try {
			handlers.put(msgClass, handlerClass.newInstance());
		} catch (InstantiationException e) {
			logger.error("initial handler failed! ", e);
		} catch (IllegalAccessException e) {
			logger.error("initial handler failed! ", e);
		}
		logger.info("message registered[msg=" + msgClass.getSimpleName() + ",id=" + msgId + "]");
	}

	@SuppressWarnings("unchecked")
	public <M extends T> M getMessage(int msgId) {
		try {
			Class<? extends T> msgClass = msgClasses.get(msgId);
			if (msgClass == null) {
				return null;
			}
			return (M) msgClass.newInstance();
		} catch (InstantiationException e) {
			logger.error("initial message failed! ", e);
		} catch (IllegalAccessException e) {
			logger.error("initial message failed! ", e);
		}
		return null;
	}

	@SuppressWarnings("unchecked")
	public <M extends T, H extends IMessageHandler<M>> H getHandler(Class<M> msgClass) {
		if (handlers.containsKey(msgClass)) {
			return (H) handlers.get(msgClass);
		}
		if (!msgAndHandlerClasses.containsKey(msgClass)) {
			logger.error(msgClass.getName() + "未注册处理器。 ");
			return null;
		}
		try {
			IMessageHandler<? extends T> handler = msgAndHandlerClasses.get(msgClass).newInstance();
			handlers.put(msgClass, handler);
			return (H) handler;
		} catch (InstantiationException e) {
			logger.error("initial handler failed! ", e);
		} catch (IllegalAccessException e) {
			logger.error("initial handler failed! ", e);
		}
		return null;
	}
	
	/**
	 * 获取消息id
	 * @param msgClass
	 * @return
	 */
	public <M extends T> int getMessageId(Class<M> msgClass){
		if(classeMsgs.containsKey(msgClass)){
			return classeMsgs.get(msgClass);
		}
		return 0;
	}

}
